<script setup lang="ts">
import { debounce } from "lodash";
import { ref } from "vue";
import {
  editInspectionRoute,
  queryAreaInfoList,
  queryPoints,
} from "@/api/pipe/index";
import { Plus, Minus } from "@element-plus/icons-vue";
import { getPolygonCentroid } from "@/views/inspection-plan/line/utils";
import { useMapStore } from "@/store";
import { useLocalStore } from "@/views/inspection-plan/line/store";
import { cloneDeep } from "lodash";
const props = defineProps({
  editor: {
    type: Boolean,
    deafault: false,
  },
  coords: String, // 接收父组件传过来的点位坐标
  route: Object,
});
const bStartEditing = ref(false);
const className = "_inspecton_route_edit";
const centerDialogVisible = ref(true);
const typeOptions = ref([
  { label: "按路线", value: 1 },
  { label: "按区域", value: 2 },
]);
const ruleFormRef = ref();
const wayPointList = ref<Array<any>>([]);
const loading = ref(false);
const options = ref([]);
const activeIndex = ref(-1);
const mapStore = useMapStore();
const localStore = useLocalStore();
const { selectedInspectionNode } = storeToRefs(mapStore);
const emitEvents = defineEmits(["close"]);
const selectedFeatureIdList = ref<Array<any>>([]);
const FORM_INITIAL_STATE = {
  // inspLineId: 0,
  inspLineName: "",
  inspLineType: null,
  startPositionId: null,
  startPositionName: "",
  startPosition: null,
  byWay: [],
  endPositionId: null,
  endPositionName: null,
  endPosition: null,
  jsonLine: "",
  inspPositionCount: 0, // 节点数量
};

const onChange = (value: number) => {
  bStartEditing.value = true;
  form.inspLineType = value;
  rules.endPositionId[0].required = form.inspLineType === 1;
  Object.keys(FORM_INITIAL_STATE).forEach((key) => {
    if (key !== "inspLineType") {
      form[key] = FORM_INITIAL_STATE[key];
    }
  });
  wayPointList.value = [];
  selectedFeatureIdList.value = [];
  localStore.setJsonLine(null);
  localStore.setSelectedFeatureIdList([]);
};
const form = props.editor
  ? reactive<any>({ ...props.route })
  : reactive({ ...FORM_INITIAL_STATE });
const rules = reactive({
  inspLineName: [
    {
      required: true,
      message: "请输入巡检路线名称",
    },
  ],
  inspLineType: [
    {
      required: true,
      message: "请选择巡检类型",
    },
  ],
  startPositionId: [
    {
      required: true,
      message: [
        "请在地图上选择设备或输入设备名称",
        "请在地图上选择区域或输入区域名称",
      ][Math.max(0, form.inspLineType - 1)],
    },
  ],
  byWay: [
    {
      required: true,
      message: ["请选择途径点", "请选择途径区域"][
        Math.max(0, form.inspLineType - 1)
      ],
    },
  ],
  endPositionId: [
    {
      required: form.inspLineType === 1,
      message: ["请选择巡检终点", "请选择终点区域"][
        Math.max(0, form.inspLineType - 1)
      ],
    },
  ],
});

const onSubmit = async (formEl) => {
  rules.endPositionId[0].required = form.inspLineType === 1;
  console.log(wayPointList.value);
  activeIndex.value = -1;
  if (!formEl) return;
  await formEl.validate((valid) => {
    if (valid) {
      const validWayPointList = wayPointList.value.filter(
        (item: any) => item.coordinates
      );
      let pointCount = validWayPointList.length + 1;
      if (form.endPosition) {
        pointCount += 1;
      }
      if (pointCount > 1) {
        const coordinates = [
          form.startPosition.coordinates,
          ...validWayPointList.map((item) => item.coordinates),
        ];
        if (form.endPosition) {
          coordinates.push(form.endPosition.coordinates);
        }
        form.jsonLine = JSON.stringify({
          type: "LineString",
          coordinates,
        });
      } else if (pointCount === 1) {
        form.jsonLine = JSON.stringify({
          type: "Point",
          coordinates: form.startPosition.coordinates,
        });
      }
      form.byWay = wayPointList.value;
      form.inspPositionCount = pointCount;
      editInspectionRoute(form).then(({ succeeded }: any) => {
        if (succeeded) {
          ElMessage({
            message: "已保存成功！",
            type: "success",
          });
        } else {
          ElMessage({
            message: "保存失败！",
            type: "warning",
          });
        }
        if (props.editor) {
          mapStore.setEditingInspectionRoute(null);
        }
        emitEvents("close");
        localStore.setJsonLine(null);
        localStore.setSelectedFeatureIdList([]);
        mapStore.setEditingInspectionRoute(null);
      });
    }
  });
};

// 放抖
const debounce_fun = debounce(onSubmit, 1000);

const addWayPoint = (index: number) => {
  wayPointList.value.splice(index, 0, {});
};
const subWayPoint = (index: number) => {
  wayPointList.value.splice(index, 1);
};
const onPointChange = (value: string) => {
  const typeIndex = Number(form.inspLineType) - 1;
  [queryPoints, queryAreaInfoList]
    [typeIndex]({
      pageSize: 50,
      pageIndex: 1,
      queryVal: value,
      isPublish: true,
    })
    .then(({ data, succeeded }: any) => {
      if (succeeded) {
        options.value = data.items
          .filter(
            (item: any) =>
              item.jsonGeom &&
              !selectedFeatureIdList.value.includes(
                [item.pointId, item.polygonId][typeIndex]
              ) &&
              (typeIndex === 0 || item.polygonName.includes(value))
          )
          .map((item: any) => {
            let { coordinates } = JSON.parse(item.jsonGeom);
            if (typeIndex === 1) {
              coordinates = getPolygonCentroid(coordinates[0]);
            }

            return {
              value: [item.pointId, item.polygonId][typeIndex],
              label: [item.pointName, item.polygonName][typeIndex],
              coordinates,
              classId: [item.classId, item.polygonType][typeIndex],
              serial: [item.pointGisNo, item.polygonNo][typeIndex],
              del: false,
            };
          });
      }
    });
};
const saveSelectedFeatureIdList = () => {
  let list: Array<string | number> = [];
  if (form.startPosition) {
    list.push(form.startPosition.value);
  }
  list = [...list, ...wayPointList.value.map((item: any) => item.value)];
  if (form.endPosition) {
    list.push(form.endPosition.value);
  }
  selectedFeatureIdList.value = list;
};
const onStartChange = (pointId: number | string) => {
  const obj: any = options.value.find((item: any) => item.value === pointId);
  const { coordinates, serial, classId } = obj;
  if (obj) {
    form.startPositionName = obj.label;
    form.startPosition = obj;
    form.startPositionId = obj.value;
  }
  saveSelectedFeatureIdList();
};
const onWayChange = (index: number, pointId: number | string) => {
  const obj: any = options.value.find((item: any) => item.value === pointId);
  const { coordinates, serial, classId, label, value, del } = obj;
  if (obj) {
    wayPointList.value[index] = {
      coordinates,
      serial,
      classId,
      label,
      value,
      del,
    };
    form.byWay = wayPointList.value;
  }
  saveSelectedFeatureIdList();
};
const onEndChange = (pointId: number | string) => {
  const obj: any = options.value.find((item: any) => item.value === pointId);
  if (obj) {
    form.endPositionName = obj.label;
    form.endPosition = obj;
    form.endPositionId = obj.value;
  }
  saveSelectedFeatureIdList();
};
const preview = () => {
  if (form.startPosition) {
    const validWayPointList = wayPointList.value.filter(
      (item: any) => item.coordinates
    );
    const coordinates = [
      form.startPosition.coordinates,
      ...validWayPointList.map((item: any) => item.coordinates),
    ];
    if (form.endPosition) {
      coordinates.push(form.endPosition.coordinates);
    }
    const jsonLine = JSON.stringify({
      coordinates,
    });
    const selectedFeatureIdList = [
      form.startPosition.value,
      ...validWayPointList.map((item: any) => item.value),
    ];
    if (form.endPosition) {
      selectedFeatureIdList.push(form.endPosition.value);
    }
    localStore.setSelectedFeatureIdList(selectedFeatureIdList);
    localStore.setJsonLine(jsonLine);
    return;
  }
  ElMessage.warning("请先完善表单！");
};
onMounted(() => {
  setTimeout(() => {
    let box = document.querySelector("." + className);
    if (box) {
      // 获取.el-overlay-dialog父级
      let boxa: any = box.parentNode;
      // 使用pointerEvents 进行页面穿透
      boxa.style.pointerEvents = "none";
      boxa.parentNode.style.pointerEvents = "none";
      boxa.parentNode.style.background = "unset";
    }
  }, 500);
});
onUnmounted(() => {
  mapStore.setCanSelectPipePointFlag(false);
  mapStore.setCanSelectAreaFlag(false);
});

watchEffect(() => {
  if (form.inspLineType === 1) {
    mapStore.setCanSelectPipePointFlag(activeIndex.value !== -1);
  } else if (form.inspLineType === 2) {
    mapStore.setCanSelectAreaFlag(activeIndex.value !== -1);
  }
});
watchEffect(() => {
  if (selectedInspectionNode.value && activeIndex.value !== -1) {
    const {
      pointId,
      pointName,
      coordinates,
      polygonName,
      polygonId,
      classId,
      serial,
    } = selectedInspectionNode.value;
    const id = [pointId, polygonId][form.inspLineType - 1];
    const name = [pointName, polygonName][form.inspLineType - 1];
    if (activeIndex.value === 0) {
      form.startPosition = { coordinates, classId, serial };
      form.startPositionId = id;
      form.startPositionName = name;
    } else if (activeIndex.value === 1 + wayPointList.value.length) {
      form.endPosition = { coordinates, classId, serial };
      form.endPositionId = id;
      form.endPositionName = name;
    } else {
      wayPointList.value[activeIndex.value - 1] = {
        label: name,
        value: id,
        coordinates,
      };
      form.byWay = wayPointList.value;
    }

    activeIndex.value = -1;
    mapStore.setSelectedInspectionNode(null);
  }
});
watchEffect(() => {
  if (props.editor && props.route) {
    wayPointList.value = cloneDeep(props.route.byWay);
    centerDialogVisible.value = true;
    bStartEditing.value = true;
  }
});
watchEffect(() => {
  if (form.inspLineType === 2) {
    localStore.setSelectedFeatureIdList([...selectedFeatureIdList.value]);
  }
});
onUnmounted(() => {
  localStore.setSelectedFeatureIdList([]);
});
</script>

<template>
  <el-dialog
    v-model="centerDialogVisible"
    :title="editor ? '修改巡检路线' : '新增巡检路线'"
    width="540"
    align-center
    draggable
    :class="className"
    :close-on-click-modal="false"
    style="pointer-events: auto"
    @close="emitEvents('close')"
  >
    <el-form
      ref="ruleFormRef"
      :model="form"
      class="content"
      label-position="right"
      label-width="125px"
      :key="form.inspLineType"
    >
      <el-scrollbar max-height="500">
        <el-form-item label="巡检方向：" prop="inspLineType">
          <el-select
            v-model="form.inspLineType"
            placeholder="请选择巡检方向"
            @change="onChange"
            :disabled="!!editor"
            :rules="rules.inspLineType"
          >
            <el-option
              v-for="item in typeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          label="路线名称："
          prop="inspLineName"
          :rules="rules.inspLineName"
        >
          <el-input
            v-model="form.inspLineName"
            placeholder="请输入路线名称"
            maxlength="10"
            @input="
              (v) => (form.inspLineName = v.replace(/[^\w_\u4e00-\u9fa5]/g, ''))
            "
          />
        </el-form-item>
        <template v-if="bStartEditing">
          <el-form-item
            :label="['选择巡检起点：', '选择起点区域：'][form.inspLineType - 1]"
            :rules="rules.startPositionId"
            prop="startPositionId"
          >
            <el-select
              v-model="form.startPositionName"
              filterable
              remote
              reserve-keyword
              :placeholder="
                [
                  '在地图上选择设备或输入设备名称/编码',
                  '在地图上选择区域或输入区域名称',
                ][form.inspLineType - 1]
              "
              remote-show-suffix
              :remote-method="onPointChange"
              :loading="loading"
              style="margin-right: 10px"
              @change="onStartChange"
              @focus="activeIndex = 0"
            >
              <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
            <el-button circle class="addBtn" @click="addWayPoint(0)">
              <el-icon color="blue">
                <Plus />
              </el-icon>
            </el-button>
            <span class="deleteTips">{{
              form.startPosition?.del === true ? "(已删除)" : ""
            }}</span>
          </el-form-item>
          <el-form-item
            v-for="(wayPoint, index) in wayPointList"
            :key="wayPoint"
            :label="['选择途径点：', '选择途径区域：'][form.inspLineType - 1]"
            :rules="rules.byWay"
            prop="byWay"
          >
            <el-select
              v-model="wayPointList[index].label"
              filterable
              remote
              reserve-keyword
              :placeholder="
                [
                  '在地图上选择设备或输入设备名称/编码',
                  '在地图上选择区域或输入区域名称',
                ][form.inspLineType - 1]
              "
              remote-show-suffix
              :remote-method="onPointChange"
              :loading="loading"
              style="margin-right: 10px"
              @change="(value: string | number) => onWayChange(index, value)"
              @focus="activeIndex = 1 + index"
            >
              <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
            <el-button circle class="addBtn" @click="addWayPoint(1 + index)">
              <el-icon color="blue">
                <Plus />
              </el-icon>
            </el-button>
            <el-button circle class="minusBtn" @click="subWayPoint(index)">
              <el-icon color="red">
                <Minus />
              </el-icon>
            </el-button>
            <span class="deleteTips">{{
              wayPoint?.del === true ? "(已删除)" : ""
            }}</span>
          </el-form-item>
          <el-form-item
            :label="['选择巡检终点：', '选择终点区域：'][form.inspLineType - 1]"
            :rules="rules.endPositionId"
            prop="endPositionId"
          >
            <el-select
              v-model="form.endPositionName"
              filterable
              remote
              reserve-keyword
              :placeholder="
                [
                  '在地图上选择设备或输入设备名称/编码',
                  '在地图上选择区域或输入区域名称',
                ][form.inspLineType - 1]
              "
              remote-show-suffix
              :remote-method="onPointChange"
              :loading="loading"
              style="margin-right: 10px"
              @change="onEndChange"
              @focus="activeIndex = 1 + wayPointList.length"
            >
              <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
            <span class="deleteTips">{{
              form.endPosition?.del === true ? "(已删除)" : ""
            }}</span>
          </el-form-item>
        </template>
      </el-scrollbar>
      <el-form-item class="twoButtons">
        <el-button type="primary" style="width: 100px" @click="preview"
          >预览</el-button
        >
        <el-button
          type="primary"
          style="width: 100px"
          @click="debounce_fun(ruleFormRef)"
          >保存</el-button
        >
        <el-button
          style="width: 100px"
          @click="
            centerDialogVisible = false;
            activeIndex = -1;
            emitEvents('close');
            localStore.setJsonLine([]);
            localStore.setSelectedFeatureIdList([]);
            mapStore.setEditingInspectionRoute(null);
          "
          >取消</el-button
        >
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<style scoped lang="scss">
.content {
  padding: 10px 0 0;

  :deep(.el-input) {
    width: 295px;
    margin-right: 10px;
  }

  :deep(.el-select) {
    width: 295px;
  }
}

.addBtn {
  width: 16px;
  height: 16px;
  border-color: blue;
}

.minusBtn {
  width: 16px;
  height: 16px;
  border-color: red;
}

.twoButtons {
  :deep(.el-form-item__content) {
    display: flex;
    justify-content: space-around;
    margin: 30px 50px 0 !important;
  }
}

.deleteTips {
  color: red;
  margin-left: 5px;
  position: absolute;
  right: 5px;
}
</style>
